#pragma once
#include <vector>
//#include <typeinfo>

template<typename T>void tracking(const std::vector<T>& v);

template<typename T>
inline void tracking(const std::vector<T>& v)//��� ������� ������ ����������???
{
	std::cout << "size: " << v.size() << " " << "capacity: " << v.capacity() << " " << "max_size: " << v.max_size()<< std::endl;
	typename std::vector<T>::const_iterator Ib = v.begin(), Ie = v.end();

	while (Ib != Ie)// � ������� ����������� ������������ ���������� �������������� []
	{
		std::cout << *Ib << " ";
		++Ib;
	}
	std::cout << std::endl;
	
}

template<class Container>
inline void print(const Container& v)
{
	std::cout << typeid(v).name() << std::endl;
	typename Container::const_iterator Ib = v.begin(), Ie = v.end(); //��� �� �������????
	
	if (v.size())
	{
		while (Ib != Ie)
		{
			std::cout << *Ib << " ";
			++Ib;
		}
	}
	else std::cout << "Empty Container";
	std::cout << std::endl;
}

template<typename T>
inline void tracking(const std::vector<T*>& v)
{
	std::cout << "size: " << v.size() << " " << "capacity: " << v.capacity() << " " << "max_size: " << v.max_size() << std::endl;
	
	typename std::vector<T*>::const_iterator Ib = v.begin(), Ie = v.end();
	
	if(*Ib)
	{ 
	while (Ib != Ie)
	{
		std::cout << **Ib << " ";
		++Ib;
	}
	std::cout << std::endl;
	}else std::cout << "Empty vector"<< std::endl;
}

template<typename T>
std::ostream& operator<<(std::ostream& os, const std::vector<T>& vv)
{
	typename std::vector<T>::const_iterator Ib = vv.begin(), Ie = vv.end();
	
	/*for (size_t i = 0; Ibvv != Ievv; i++)
	{
		typename std::vector<T>::const_iterator Ib = vv[i].begin(), Ie = vv[i].end();*/

		while (Ib != Ie)
		{
			os << *Ib << " ";
			++Ib;
		}
		os << std::endl;
		
		///++Ibvv;
	//}	
	return os;
}


template<typename T>
inline void insert_if_not(std::vector<T>& v, const T& inserted)
{
	typename std::vector<T>::const_iterator Ib = v.begin(), Ie = v.end();
	
	while (Ib != Ie)
	{
		if (*Ib == inserted) { return; }
		++Ib;
	}
	
	v.insert(v.begin(), inserted);
}

template<typename T>
inline void insert_between(std::vector<T>& v, const T& inserted)
{
	typename std::vector<T>::const_iterator Ib = v.begin(), Ie = v.end();

	int size_v = v.size();

	for(int i = 0; i<size_v; i++)
	{
		Ib = v.insert(Ib, inserted);
		++Ib;
		++Ib;
	}
}

template<typename T>
inline void delete_repeated(std::vector<T>& v, const int& sign = 0)
{
	typename std::vector<T>::const_iterator Ib = v.begin();
	typename std::vector<T>::const_iterator Id_1 = Ib;
	typename std::vector<T>::const_iterator Id_2 = Id_1;
	
	while (Ib != v.end())
	{		
		Id_2 = Id_1 = Ib;						
		++Ib;
		if (Ib == v.end()) break;

		if (*Id_2 == *Ib)
		{
			do
			{
				++Ib;
				if (Ib == v.end()) {break;}
			} while (*Id_2 == *Ib);
			
			Id_2 = Ib;
			
			Ib = v.erase(Id_1, Id_2);
		}				
	}
}

template<typename T>
inline void delete_dublicate(std::vector<T>& v)
{
	typename std::vector<T>::const_iterator Ib = v.begin();
	typename std::vector<T>::const_iterator Id_1 = Ib;

	while (Ib != v.end()-1)
	{
		Id_1 = Ib+1;
				
		while (Id_1 != v.end())
		{
			if (*Ib == *Id_1)
			{
				Id_1 = v.erase(Id_1);
			} else 	++Id_1;
		}
		++Ib;
	}
}